﻿namespace Api.Controllers;

/// <summary>
/// 认证
/// </summary>
/// <param name="configuration"></param>
/// <param name="userBLL"></param>
/// <param name="roleBLL"></param>
/// <param name="loginLogBLL"></param>
/// <param name="hubContext"></param>
/// <param name="operationLogBLL"></param>
[Route("api/[controller]/[action]")]
[ApiController]
[Authorize]
public class AuthController(IConfiguration configuration, IUserBLL userBLL, IRoleBLL roleBLL, ILoginLogBLL loginLogBLL, IHubContext<LoginHub> hubContext, IOperationLogBLL operationLogBLL) : BaseController(operationLogBLL)
{
    private readonly IConfiguration _configuration = configuration;
    private readonly IUserBLL _userBLL = userBLL;
    private readonly IRoleBLL _roleBLL = roleBLL;
    private readonly ILoginLogBLL _loginLogBLL = loginLogBLL;
    private readonly IHubContext<LoginHub> _hubContext = hubContext;

    #region 获取权限
    /// <summary>
    /// 获取权限
    /// </summary>
    [HttpPost]
    public async Task<ResultModel<LoginResVM>> GetAuth(AccountsRM login)
    {
        ResultModel<LoginResVM> result = new ResultModel<LoginResVM>();
        try
        {
            User user = await _userBLL.GetUserByAccountAsync(login.Account);
            int roleId = Convert.ToInt32(_configuration["IDSDefaultRoleId"]);
            Role role = new Role();
            if (user == null)
            {
                user = new User
                {
                    UserId = login.UserId,
                    Account = login.Account,
                    Name = login.Name,
                    Type = login.Type,
                    Gender = login.Gender,
                    OrgCode = login.OrgCode,
                    OrgName = login.OrgName,
                    Avatar = login.Avatar,
                    Enable = 1
                };
                if (login.IsAdmin)
                {
                    user.RoleId = 1;
                    user.Roles = [1];
                    await _userBLL.AddUserAsync(user);
                    role = await _roleBLL.GetRoleByIdAsync(user.RoleId);
                }
                else
                {
                    role = await _roleBLL.GetRoleByIdAsync(roleId);
                    if (role != null)
                    {
                        user.RoleId = roleId;
                        user.Roles = [roleId];
                        await _userBLL.AddUserAsync(user);
                    }
                    else
                    {
                        return new ResultModel<LoginResVM>
                        {
                            code = -1,
                            msg = $"该用户没有权限"
                        };
                    }
                }
            }
            else
            {
                user.UserId = login.UserId;
                role = await _roleBLL.GetRoleByIdAsync(user.RoleId);
                if (role == null)
                {
                    return new ResultModel<LoginResVM>
                    {
                        code = -1,
                        msg = $"该用户没有权限"
                    };
                }
                if (role.Enable == 2)
                {
                    return new ResultModel<LoginResVM>
                    {
                        code = -1,
                        msg = $"该用户角色被禁用"
                    };
                }
                if (login.IsAdmin)
                {
                    user.RoleId = 1;
                    user.Enable = 1;
                    if (!user.Roles.Contains(1))
                    {
                        user.Roles.Add(1);
                    }
                }
                else
                {
                    if (user.Enable == 2)
                    {
                        return new ResultModel<LoginResVM>
                        {
                            code = -1,
                            msg = $"该用户被禁用"
                        };
                    }
                }
                if (user.Id == 1)
                {
                    user.RoleId = 1;
                    if (!user.Roles.Contains(1))
                    {
                        user.Roles.Add(1);
                    }
                }
                user.Name = login.Name;
                user.Type = login.Type;
                user.Gender = login.Gender;
                user.Avatar = login.Avatar;
                user.OrgCode = login.OrgCode;
                user.OrgName = login.OrgName;
                await _userBLL.UpdateUserAsync(user);
            }
            var users = await RedisStaticHelper.GetAsync<UserVM>(login.Account);
            if (users != null && !string.IsNullOrWhiteSpace(users.ConnectionId))
            {
                //一个系统一个账号登录
                if (users.ConnectionId != login.ConnectionId)
                {
                    await _hubContext.Clients.Client(users.ConnectionId).SendAsync("HubShowMsg",
                        new HubSendMessage() { Account = users.Account, Msg = "您的账号在其它终端登录，您已被迫下线！" });
                }
            }
            user = await _userBLL.GetUserByAccountAsync(login.Account);
            List<Feature> features = await _roleBLL.GetFeatureListByRoleIdAsync(user.RoleId);
            UserVM userVM = MapperHelper.Mapper<UserVM, User>(user);
            userVM.ConnectionId = login.ConnectionId;
            userVM.Name = login.Name;
            if (await RedisStaticHelper.ExistsAsync($"loginrole_{login.Account}"))
            {
                await RedisStaticHelper.RemoveAsync($"loginrole_{login.Account}");
                await RedisStaticHelper.SetAsync($"loginrole_{login.Account}", userVM.RoleId, TimeSpan.FromHours(1));
            }
            else
            {
                await RedisStaticHelper.SetAsync($"loginrole_{login.Account}", userVM.RoleId, TimeSpan.FromHours(1));
            }
            await RedisStaticHelper.SetAsync(userVM.Account, userVM, TimeSpan.FromHours(1));
            #region 添加登录日志
            var token = Util.MD5Encrypt(Guid.NewGuid().ToString());
            await _loginLogBLL.AddLoginLogAsync(new AddLoginLogInput
            {
                UserId = user.Id,
                Account = user.Account,
                Name = user.Name,
                Ip = Request.HttpContext.Connection.RemoteIpAddress == null ? string.Empty : Request.HttpContext.Connection.RemoteIpAddress.ToString(),
                RoleId = user.RoleId,
                RoleName = role != null ? role.Name : string.Empty,
                LoginTime = DateTime.Now,
                Token = token
            });

            LoginLogMqttRM loginLogMqttRM = new LoginLogMqttRM
            {
                Uid = login.Account,
                UserId = login.UserId,
                Name = login.Name,
                RoleName = role != null ? role.Name : string.Empty,
                CommonType = (int)LogType.Login,
                Ip = Request.HttpContext.Connection.RemoteIpAddress == null ? string.Empty : Request.HttpContext.Connection.RemoteIpAddress.ToString(),
                Session = token,
                ClientType = 0
            };

            var fmMqttClient = new FmMqttClient();
            fmMqttClient.Publish(JsonConvert.SerializeObject(loginLogMqttRM));
            #endregion
            result.code = 1;
            result.data = new LoginResVM
            {
                UserInfo = userVM,
                FeatureList = features
            };
            result.count = 0;
        }
        catch (Exception ex)
        {
            Log.WriteException(ex);
            result.code = -1;
            result.msg = ex.Message;
        }
        return result;
    }
    #endregion

    #region 获取系统软授权信息
    /// <summary>
    /// 获取系统软授权信息
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    [AllowAnonymous]
    public ResultModel<SFAuthModel> GetAuthInfo()
    {
        return OperationExecuteReturnData(() =>
        {
            return SoftwareAuthorization.GetAuth();
        });
    }
    #endregion

    #region 获取软授权到期前X天提醒
    /// <summary>
    /// 获取软授权到期前X天提醒
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public ResultModel<string> GetAuthInfoRemider()
    {
        return OperationExecuteReturnData(() =>
        {
            var sfConfig = _configuration["SFAuthExpiresReminderDayByPage"];
            var config_day = sfConfig == null ? 0 : Convert.ToInt32(sfConfig);
            if (config_day <= 0)
            {
                return "";
            }
            var sf = SoftwareAuthorization.GetAuth();
            if (DateTime.Now.Date.AddDays(config_day) >= DateTime.Parse(sf.expiredate).AddDays(1))
            {
                return $"{sf.expiredate}";
            }
            return "";
        });
    }
    #endregion
}
